package com.googlecode.simplexer.exception;

import com.googlecode.simplexer.validator.Validator;

/**
 * 
 * @author Sam Huang
 */
public class ParseException extends RuntimeException {
	private static final long serialVersionUID = -3145453841123519571L;

	protected String fileName;

	protected String message = null;

	protected String line;

	protected String token;

	protected String[] expected;

	protected Validator[] verifiers;

	protected char chr;

	protected int ln;

	protected int column;

	protected int length;

	public ParseException() {

	}

	public ParseException(String msg) {
		super(msg);
		this.message = msg;
	}

	public ParseException(String line, int ln, int column, String msg) {
		super(msg);
		this.message = msg;
	}

	public String toString() {
		StringBuffer buffer = new StringBuffer("\n" + fileName + " [" + ln
				+ "|" + column + "]:\n" + line.trim() + "\n");
		for (int i = 0; i < column - 1; i++) {
			buffer.append(" ");
		}
		buffer.append("^\n");
		buffer.append("encountered token \"" + token + "\",\n");
		if (expected != null || verifiers != null) {
			buffer
					.append("one or more tokens of the following are expected:\n");
			buffer.append(chr + ",\n");
			if (expected != null) {
				for (String ex : expected) {
					buffer.append(ex + ",\n");
				}
			}
			if (verifiers != null) {
				for (Validator verifier : verifiers) {
					buffer.append(verifier.toString() + ",\n");
				}
			}
		} else if (message != null) {
			buffer.append(message);
		}
		return buffer.toString();
	}

	/**
	 * @return the column
	 */
	public int getColumn() {
		return column;
	}

	/**
	 * @param column
	 *            the column to set
	 */
	public void setColumn(int column) {
		this.column = column;
	}

	/**
	 * @return the expected
	 */
	public String[] getExpected() {
		return expected;
	}

	/**
	 * @param expected
	 *            the expected to set
	 */
	public void setExpected(String... expected) {
		this.expected = expected;
	}

	public void setExpected(Validator... verifiers) {
		this.verifiers = verifiers;
	}

	public void setExpected(int length) {
		this.length = length;
	}

	public void setExpected(char chr) {
		this.chr = chr;
	}

	/**
	 * @return the line
	 */
	public String getLine() {
		return line;
	}

	/**
	 * @param line
	 *            the line to set
	 */
	public void setLine(String line) {
		this.line = line;
	}

	/**
	 * @return the ln
	 */
	public int getLineNumber() {
		return ln;
	}

	/**
	 * @param ln
	 *            the ln to set
	 */
	public void setLineNumber(int ln) {
		this.ln = ln;
	}

	/**
	 * @return the token
	 */
	public String getToken() {
		return token;
	}

	/**
	 * @param token
	 *            the token to set
	 */
	public void setToken(String token) {
		this.token = token;
	}

	/**
	 * @return the fileName
	 */
	public String getFileName() {
		return fileName;
	}

	/**
	 * @param fileName
	 *            the fileName to set
	 */
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message
	 *            the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}
}
